package org.shangrila.app.schedule;

import java.util.Date;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.time.FastDateFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * Spring Schedule 提供三种形式的定时任务 * 启动类上面加个@EnableScheduling注解就Ok。
 * @SpringBootApplication
 * @EnableScheduling
 * 
 * @author sophie
 *
 */
@Component
public class ScheduleJobs {
	private static final Logger log = LoggerFactory.getLogger(ScheduleJobs.class);

	public final static long SECOND = 1 * 1000;
	FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");

	// 固定等待时间 @Scheduled(fixedDelay = 时间间隔 )  fixDelay的计时是相对于上一次调用的时间的
	//@Scheduled(initialDelay = 1000,fixedDelay = SECOND * 2)  //第1次延时1秒后执行，当执行完后2秒再执行
	public void fixedDelayJob() throws InterruptedException {
		TimeUnit.SECONDS.sleep(2);
		log.info("[FixedDelayJob Execute]" + fdf.format(new Date()));
	}

	// 固定间隔时间 @Scheduled(fixedRate = 时间间隔 ) fixRate的计时是相对于系统时间的，也就是一定相隔会固定时间执行。
	//@Scheduled(fixedRate = SECOND * 4)  //每隔4秒钟执行一次
	public void fixedRateJob() {
		log.info("[FixedRateJob Execute]" + fdf.format(new Date()));
	}

	// Corn表达式 @Scheduled(cron = Corn表达式)
	@Scheduled(cron = "0/5 * * * * ?")  //每隔5秒钟执行一次
	public void cronJob() {
		log.info("[CronJob Execute]" + fdf.format(new Date()));
	}

	public static void main(String[] args) throws InterruptedException {
		ScheduleJobs s = new ScheduleJobs();
		//s.fixedDelayJob();
		//s.fixedRateJob();
		s.cronJob();
		System.exit(0);
	}

}

/*

Scheduled参数

Scheduled主要支持 fixRate , fixDelay , cron , initialDelay 这些参数，下面做简要说明。

fixRate和fixDelay

fixRate和fixDelay参数都指定了函数每隔某个毫秒数执行一次，但是他们之间也有细小的差别。

fixRate

fixRate的计时是相对于系统时间的，也就是一定相隔会固定时间执行。

fixDelay

fixDelay的计时是相对于上一次调用的时间的，因此他受其他程序调用的影响，如果该函数在其他地方被手动调用，那么这个计时器就会重新计时。

initialDelay参数

initialDelay参数是个额外参数，比较简单，就是指定从项目开始运行到该函数首次被调用的执行时间，以毫秒计。

如果不指定这个参数，这个值就是-1，也就是程序开始时不执行。

在不知到initialDelay这个参数的时候为了让程序启动时立即调用该函数，我让这个定时类继承了 InitializingBean 并在重写的 afterPropertiesSet 方法中手动调用了这个函数。。。现在看起来还真是愚蠢。。。

cron

这个Cron是最复杂也是高度自定义化的定时工具，在Linux系统里也有类似的crontab命令。他其实是更加细致的定义了定时任务，以一个字符串的形式进行表示。

在SpringBoot中，一个cron字符串是由六个部分以空格组成的字符串，文档中的例子是这样的：
"0 0 * * * *" = the top of every hour of every day.
 "*\10 * * * * *" = every ten seconds.
"0 0 8-10 * * *" = 8, 9 and 10 o'clock of every day.
"0 0 6,19 * * *" = 6:00 AM and 7:00 PM every day.
"0 0/30 8-10 * * *" = 8:00, 8:30, 9:00, 9:30, 10:00 and 10:30 every day.
"0 0 9-17 * * MON-FRI" = on the hour nine-to-five weekdays
"0 0 0 25 12 ?" = every Christmas Day at midnight
六个部分分别表示秒、分、时、日、月、周。

他支持'-‘表示范围，'*'表示通配，'/‘表示在左边的时间匹配后间隔右边的时间，'?'一般表示周的通配。

具体的使用方法还要参考相关文档。

注意点

在实际使用Scheduled注解时，我们一定要指定且仅仅指定fixRate、fixDelay、cron当中的一个，否则肯定会导致错误。当然，我们可以任意指定initialDelay参数。

*/
